﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Autodesk.Revit.UI;
using Win32;

namespace ShowGridNumber
{
	public partial class GridNumberForm : System.Windows.Forms.Form
	{
		public GridNumberForm(ShowGridApplication application)
		{
			this.m_appShowGrid = application;
			this.InitializeComponent();
		}

		[DllImport("user32.dll", CharSet = CharSet.Auto)]
		public static extern IntPtr CallWindowProc(IntPtr wndProc, IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

		[DllImport("user32.dll", CharSet = CharSet.Auto)]
		public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

		[DllImport("user32.dll", CharSet = CharSet.Auto)]
		public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, GridNumberForm.NewWndProc wndproc);

		[DllImport("user32.dll")]
		public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

		private void GridNumberForm_Load(object sender, EventArgs e)
		{
			this.GetMDIChildWindowHandle();
		}

		private void GetMDIChildWindowHandle()
		{
			IntPtr zero = IntPtr.Zero;
			try
			{
				IntPtr mainWindowHandle = Process.GetCurrentProcess().MainWindowHandle;
				this.m_hMDIChildHandle = DllImportManeger.FindWindowEx(mainWindowHandle, IntPtr.Zero, "MDIClient", "");
			}
			catch
			{
			}
			finally
			{
				Marshal.FreeHGlobal(zero);
			}
		}

		private void GridNumberForm_FormClosed(object sender, FormClosedEventArgs e)
		{
			if (IntPtr.Zero != this.m_hWndChildClientProcOld)
			{
				GridNumberForm.SetWindowLong(this.m_hWndChildClientHandle, -4, this.m_hWndChildClientProcOld);
			}
			if (IntPtr.Zero != this.m_hWndChildProcOld)
			{
				GridNumberForm.SetWindowLong(this.m_hWndChildHandle, -4, this.m_hWndChildProcOld);
			}
			this.m_font.Dispose();
		}

		public IntPtr WndMsgProcChildClient(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
		{
			IntPtr result;
			try
			{
				IntPtr intPtr = GridNumberForm.CallWindowProc(this.m_hWndChildClientProcOld, hWnd, msg, wParam, lParam);
				if (msg <= 32)
				{
					if (msg != 2)
					{
						if (msg != 32)
						{
						}
					}
					else
					{
						GridNumberForm.SetWindowLong(this.m_hWndChildClientHandle, -4, this.m_hWndChildClientProcOld);
						this.m_hWndChildClientProcNew = null;
						base.Hide();
					}
				}
				else if (msg != 512)
				{
					switch (msg)
					{
					case 519:
						this.m_midButtonDown = true;
						break;
					case 520:
						this.m_midButtonDown = false;
						break;
					case 521:
					case 522:
						this.DrawGridNumText(false);
						break;
					}
				}
				else if (this.m_midButtonDown)
				{
					this.DrawGridNumText(false);
				}
				result = intPtr;
			}
			catch (Exception)
			{
				result = IntPtr.Zero;
			}
			return result;
		}

		public IntPtr WndMsgProcChild(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
		{
			IntPtr result;
			try
			{
				IntPtr intPtr = GridNumberForm.CallWindowProc(this.m_hWndChildProcOld, hWnd, msg, wParam, lParam);
				if (msg != 2)
				{
					if (msg != 5)
					{
						switch (msg)
						{
						case 532:
						case 534:
							this.DrawGridNumText(false);
							break;
						}
					}
					else
					{
						this.DrawGridNumText(false);
					}
				}
				else
				{
					GridNumberForm.SetWindowLong(this.m_hWndChildHandle, -4, this.m_hWndChildProcOld);
					this.m_hWndChildProcNew = null;
					base.Hide();
				}
				result = intPtr;
			}
			catch (Exception)
			{
				result = IntPtr.Zero;
			}
			return result;
		}

		public void RefreshDocAndView(UIDocument uiDoc)
		{
			if (uiDoc == null)
			{
				return;
			}
			this.m_uiDoc = uiDoc;
			if (this.m_GridNumShowMag == null)
			{
				this.m_GridNumShowMag = new GridNumberShowManager(uiDoc);
			}
			else
			{
				this.m_GridNumShowMag.RefreshUIDocument(this.m_uiDoc);
			}
			IntPtr intPtr = IntPtr.Zero;
			try
			{
				this.m_hWndChildHandle = (IntPtr)Functions.SendMessage(this.m_hMDIChildHandle, 553u, 0, 0);
				if (this.m_hWndChildProcNew == null)
				{
					this.m_hWndChildProcNew = new GridNumberForm.NewWndProc(this.WndMsgProcChild);
				}
				this.m_hWndChildProcOld = GridNumberForm.SetWindowLong(this.m_hWndChildHandle, -4, this.m_hWndChildProcNew);
				intPtr = Marshal.StringToHGlobalAnsi("AfxFrameOrView");
				DllImportManeger.EnumChildWindows(this.m_hWndChildHandle, new DllImportManeger.CallBack(this.EnumMDIChildClient), intPtr);
				if (this.m_hWndChildClientProcNew == null)
				{
					this.m_hWndChildClientProcNew = new GridNumberForm.NewWndProc(this.WndMsgProcChildClient);
				}
				this.m_hWndChildClientProcOld = GridNumberForm.SetWindowLong(this.m_hWndChildClientHandle, -4, this.m_hWndChildClientProcNew);
			}
			catch (Exception)
			{
				this.m_appShowGrid.DrawGridNumber = false;
			}
			finally
			{
				Marshal.FreeHGlobal(intPtr);
			}
		}

		public bool UnLoad()
		{
			if (this.m_hWndChildClientProcNew != null)
			{
				GridNumberForm.SetWindowLong(this.m_hWndChildHandle, -4, this.m_hWndChildProcOld);
				GridNumberForm.SetWindowLong(this.m_hWndChildClientHandle, -4, this.m_hWndChildClientProcOld);
				return false;
			}
			return true;
		}

		private bool EnumMDIChildClient(IntPtr hwnd, IntPtr ptrKey)
		{
			try
			{
				string value = Marshal.PtrToStringAnsi(ptrKey);
				StringBuilder stringBuilder = new StringBuilder(512);
				DllImportManeger.GetClassName(hwnd, stringBuilder, stringBuilder.Capacity);
				if (stringBuilder.ToString().Contains(value))
				{
					this.m_hWndChildClientHandle = hwnd;
					return false;
				}
			}
			catch
			{
			}
			return true;
		}

		public void SetShowLinkDocGridNum(bool bShowLink)
		{
			this.m_GridNumShowMag.m_bShowLink = bShowLink;
		}

		public void DrawGridNumText(bool bIdling = false)
		{
			Graphics graphics = base.CreateGraphics();
			if (this.m_uiDoc == null || this.m_uiDoc.ActiveView == null)
			{
				graphics.Clear(Color.White);
				graphics.Dispose();
				return;
			}
            if (!this.m_appShowGrid.DrawGridNumber || (int)this.m_uiDoc.ActiveView.ViewType == 4)
			{
				graphics.Clear(Color.White);
				graphics.Dispose();
				return;
			}
			Size size = default(Size);
			Point empty = Point.Empty;
			DllImportManeger.Rect rcMDIClientWin;
			DllImportManeger.GetWindowRect(this.m_hMDIChildHandle, out rcMDIClientWin);
			CalcGridInfoResult gridNumberShowInfo = this.m_GridNumShowMag.GetGridNumberShowInfo(bIdling, rcMDIClientWin, ref empty, ref size);
			if (gridNumberShowInfo == CalcGridInfoResult.eIdling)
			{
				return;
			}
			base.Location = empty;
			base.Size = size;
			this.m_GridNumShowMag.TranformIntersectPt(base.Handle);
			graphics.SmoothingMode = SmoothingMode.AntiAlias;
			graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
			graphics.CompositingQuality = CompositingQuality.HighQuality;
			graphics.Clear(Color.White);
			Brush red = Brushes.Red;
			Pen pen = new Pen(Color.Red, 2f);
			StringFormat stringFormat = new StringFormat();
			stringFormat.Alignment = StringAlignment.Center;
			stringFormat.LineAlignment = StringAlignment.Center;
			StringFormat stringFormat2 = new StringFormat();
			stringFormat2.Alignment = StringAlignment.Near;
			stringFormat2.LineAlignment = StringAlignment.Center;
			StringFormat stringFormat3 = new StringFormat();
			stringFormat3.Alignment = StringAlignment.Far;
			stringFormat3.LineAlignment = StringAlignment.Center;
			for (int i = 0; i < this.m_GridNumShowMag.m_lstGridNumShowInfo.Count; i++)
			{
				Point cirlLocation = this.m_GridNumShowMag.m_lstGridNumShowInfo[i].CirlLocation;
				Point textLocation = this.m_GridNumShowMag.m_lstGridNumShowInfo[i].TextLocation;
				string elemText = this.m_GridNumShowMag.m_lstGridNumShowInfo[i].ElemText;
				if (this.m_GridNumShowMag.m_lstGridNumShowInfo[i].ElemClass == ElemType.eGrid)
				{
					graphics.DrawArc(pen, cirlLocation.X, cirlLocation.Y, 50, 50, 0, 360);
				}
				switch (this.m_GridNumShowMag.m_lstGridNumShowInfo[i].OutlineSide)
				{
				case OutLineSide.eUp:
				case OutLineSide.eBottom:
					graphics.DrawString(elemText, this.m_font, red, textLocation, stringFormat);
					break;
				case OutLineSide.eLeft:
					graphics.DrawString(elemText, this.m_font, red, textLocation, stringFormat2);
					break;
				case OutLineSide.eRight:
					graphics.DrawString(elemText, this.m_font, red, textLocation, stringFormat3);
					break;
				}
			}
			stringFormat.Dispose();
			stringFormat2.Dispose();
			stringFormat3.Dispose();
			graphics.Dispose();
		}

		private UIDocument m_uiDoc;

		private Font m_font = new Font("微软雅黑", 25f, GraphicsUnit.Pixel);

		private GridNumberShowManager m_GridNumShowMag;

		private GridNumberForm.NewWndProc m_hWndChildClientProcNew;

		private GridNumberForm.NewWndProc m_hWndChildProcNew;

		private IntPtr m_hWndChildClientProcOld = IntPtr.Zero;

		private IntPtr m_hWndChildProcOld = IntPtr.Zero;

		private IntPtr m_hMDIChildHandle = IntPtr.Zero;

		private IntPtr m_hWndChildHandle = IntPtr.Zero;

		private IntPtr m_hWndChildClientHandle = IntPtr.Zero;

		private bool m_midButtonDown;

		private ShowGridApplication m_appShowGrid;

		public delegate IntPtr NewWndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
	}
}
